import { genNumberColumn } from './checkConfig'

function getSheet(data, config) {
  const sheetId = config.currentSheet
  const index = data.sheetList.filter(x => x.id === sheetId)[0].index
  return data.sheet[index]
}

function mergeConfig(a, b, configA, configB) {
  const o = []
  const [numberA, conflictA] = genNumberColumn(o, configA, 'A')
  const [numberB, conflictB] = genNumberColumn(o, configB, 'B')

  return {
    a: {
      nameColumn: configA.nameColumn,
      nameTrim: configA.nameTrim,
      numberColumn: numberA,
      sheet: getSheet(a, configA),
    },
    b: {
      nameColumn: configB.nameColumn,
      nameTrim: configB.nameTrim,
      numberColumn: numberB,
      sheet: getSheet(b, configB),
    },
  }
}

function checkDup(x) {
  const dup = []
  const data = {}
  for (let i = 0; i < x.sheet.length; i += 1) {
    let name = x.sheet[i][x.nameColumn]
    if (x.nameTrim) {
      name = name.trim()
    }
    const row = {
      index: i,
      raw: x.sheet[i],
      name,
    }
    if (data[row.name] != null) {
      dup.push(row)
    } else {
      data[row.name] = row
    }
  }

  return [dup, data]
}

function checkLostAdd(config, a, b) {
  const lost = []
  const add = []
  const merge = {
    a: {},
    b: {},
  }
  // lost
  for (const i of Object.keys(a)) {
    if (b[i] == null) {
      lost.push(a[i])
    } else {
      merge.a[i] = a[i]
    }
  }
  // add
  for (const i of Object.keys(b)) {
    if (a[i] == null) {
      add.push(b[i])
    } else {
      merge.b[i] = b[i]
    }
  }

  return [lost, add, merge]
}

function mapNumberColumn(c, raw, trim) {
  const o = {}
  for (const i of Object.keys(c)) {
    let value = raw[c[i]]
    if (trim) {
      value = ('' + value).trim()
    }
    o[i] = value
  }
  return o
}

function checkDiff(config, x) {
  const diff = []
  for (const i of Object.keys(x.b)) {
    const numberA = mapNumberColumn(config.a.numberColumn, x.a[i].raw, config.a.nameTrim)
    const numberB = mapNumberColumn(config.b.numberColumn, x.b[i].raw, config.b.nameTrim)
    for (const j of Object.keys(numberB)) {
      if (numberB[j] !== numberA[j]) {
        diff.push({
          name: x.b[i].name,
          label: j,
          columnA: config.a.numberColumn[j],
          columnB: config.b.numberColumn[j],
          a: x.a[i],
          b: x.b[i],
        })
        break
      }
    }
  }

  return diff
}

export default function cmpData(a, b, configA, configB) {
  const config = mergeConfig(a, b, configA, configB)
  // DEBUG
  console.log(config)

  const [dupA, dataA] = checkDup(config.a)
  const [dupB, dataB] = checkDup(config.b)

  const [lost, add, merge] = checkLostAdd(config, dataA, dataB)

  const diff = checkDiff(config, merge)

  return {
    // A 中重复的行 (名称重复)
    dupA,
    // B 中重复的行 (名称重复)
    dupB,
    // 与 A 相比, B 缺失的行
    lost,
    // 与 A 相比, B 增加的行
    add,
    // 与 A 相比, B 不一致的行
    diff,
  }
}
